home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Presentations / Presentations ’96 / Papers ’96 / Random Numbers / Random Numbers Code / shs.c next >
Encoding:
C/C++ Source or Header  |  1996-02-11  |  11.0 KB  |  244 lines  |  [TEXT/CWIE]

  1. /*
  2.  ********************************************************************
  3.  *     SHS 180-1 Reference Implementation (with unrolled loops)     *
  4.  *             Copyright 1995-6 by Paul C. Kocher.                  *
  5.  *                                                                  *
  6.  *  This file is provided as-is, without warranty of any kind;      *
  7.  *     use at your own risk.  This file may be copied and used,     *
  8.  *     even for commercial purposes, for free.  For information,    *
  9.  *     updates, updates, or consulting help, send e-mail to the     *
  10.  *     author at pck@cryptography.com.                              *
  11.  *                                                                  *
  12.  *  EXPORT STATUS:  In informal discussions, the U.S. National      *
  13.  *     Security Agency has indicated to me that source code for     *
  14.  *     can be exported from the U.S. freely, but programs using     *
  15.  *     or incorporating this code may be restricted.  Please make   *
  16.  *     sure you understand the applicable export regulations        *
  17.  *     before doing any work with cryptography.                     *
  18.  *                                                                  *
  19.  *  For links to other cryptography source code, papers, etc. see   *
  20.  *     http://www.cryptography.com.                                 *
  21.  ********************************************************************
  22.  */
  23.  
  24. #include "shs.h"
  25.  
  26. static void shsCompress(SHS_CTX *ctx);
  27.  
  28. #define SHS_ROTL(X,n) (((X) << (n)) | ((X) >> (32-(n))))
  29. #define SHS_F1(X,Y,Z) ((((Y)^(Z))&(X))^(Z))
  30. #define SHS_F2(X,Y,Z) ((X)^(Y)^(Z))
  31. #define SHS_F3(X,Y,Z) (((X)&(Y))|((Z)&((X)|(Y))))
  32. #define SHS_F4(X,Y,Z) ((X)^(Y)^(Z))
  33.  
  34.  
  35. /*
  36.  *  SHS: Initialize context
  37.  */
  38. void shsInit(SHS_CTX *ctx) {
  39.   ctx->lenW = 0;
  40.   ctx->sizeHi = ctx->sizeLo = 0;
  41.  
  42.   /*
  43.    *  Initialize H with constants from FIPS180-1.
  44.    */
  45.   ctx->H[0] = 0x67452301L;
  46.   ctx->H[1] = 0xefcdab89L;
  47.   ctx->H[2] = 0x98badcfeL;
  48.   ctx->H[3] = 0x10325476L;
  49.   ctx->H[4] = 0xc3d2e1f0L;
  50. }
  51.  
  52.  
  53. /*
  54.  *  SHS: Add data to context.
  55.  */
  56. void shsUpdate(SHS_CTX *ctx, unsigned char *dataIn, int len) {
  57.   /*
  58.    *  Read the data into W and process blocks as they get full
  59.    *
  60.    *  NOTE: The shifts can be eliminated on big-endian machines, since 
  61.    *      the byte-to-word transformation can be done with a copy.  In 
  62.    *      assembly language on 80486+ computers, the BSWAP instruction 
  63.    *      can be used.
  64.    */
  65.   ctx->sizeLo += 8*len;
  66.   ctx->sizeHi += (ctx->sizeLo < 8*len) + (len >> 29);
  67.   while (len--) {
  68.     ctx->W[ctx->lenW / 4] <<= 8;
  69.     ctx->W[ctx->lenW / 4] |= *(dataIn++);
  70.     if (((++ctx->lenW) & 63) == 0) {
  71.       shsCompress(ctx);
  72.       ctx->lenW = 0;
  73.     }
  74.   }
  75. }
  76.  
  77.  
  78. /*
  79.  *  SHS: Generate hash value from context
  80.  */
  81. void shsFinal(SHS_CTX *ctx, unsigned char hashOut[20]) {
  82.   static unsigned char bulk_pad[64] = { 0x80,0,0,0,0,0,0,0,0,0,
  83.           0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  84.           0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  };
  85.   unsigned char length_pad[8];
  86.   int i;
  87.  
  88.   /*
  89.    *  Pad with a binary 1 (e.g. 0x80), then zeroes, then length
  90.    */
  91.   length_pad[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
  92.   length_pad[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
  93.   length_pad[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
  94.   length_pad[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
  95.   length_pad[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
  96.   length_pad[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
  97.   length_pad[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
  98.   length_pad[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
  99.   shsUpdate(ctx, bulk_pad, ((56+64) - ctx->lenW) & 63);
  100.   shsUpdate(ctx, length_pad, 8);
  101.  
  102.   /*
  103.    *  Output hash
  104.    */
  105.   for (i = 0; i < 5; i++) {
  106.     *(hashOut++) = ((unsigned char)(ctx->H[i] >> 24)) & 255;
  107.     *(hashOut++) = ((unsigned char)(ctx->H[i] >> 16)) & 255;
  108.     *(hashOut++) = ((unsigned char)(ctx->H[i] >>  8)) & 255;
  109.     *(hashOut++) = ((unsigned char)(ctx->H[i]      )) & 255;
  110.   }
  111.  
  112.   /*
  113.    *  Re-initialize the context (also zeroizes contents)
  114.    */
  115.   shsInit(ctx);
  116. }
  117.  
  118.  
  119. /*
  120.  *  SHS: Hash a block in memory
  121.  */
  122. void shsBlock(unsigned char *dataIn, int len, unsigned char hashOut[20]) {
  123.   SHS_CTX ctx;
  124.  
  125.   shsInit(&ctx);
  126.   shsUpdate(&ctx, dataIn, len);
  127.   shsFinal(&ctx, hashOut);
  128. }
  129.  
  130.  
  131. /*
  132.  *  SHS: Compression function, unrolled.
  133.  */
  134. static void shsCompress(SHS_CTX *ctx) {
  135.   int t;
  136.   register unsigned long A,B,C,D,E;
  137.  
  138.   /*
  139.    *  This can be moved into the main code block below, but doing
  140.    *  so can cause some compilers to run out of registers and resort
  141.    *  to storing intermediates in RAM.
  142.    */
  143.   for (t = 16; t <= 79; t++)
  144.     ctx->W[t] =
  145.       SHS_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
  146.  
  147.   A = ctx->H[0];
  148.   B = ctx->H[1];
  149.   C = ctx->H[2];
  150.   D = ctx->H[3];
  151.   E = ctx->H[4];
  152.  
  153.   E = SHS_ROTL(A,5)+SHS_F1(B,C,D)+E+ctx->W[ 0]+0x5a827999L; B=SHS_ROTL(B,30); 
  154.   D = SHS_ROTL(E,5)+SHS_F1(A,B,C)+D+ctx->W[ 1]+0x5a827999L; A=SHS_ROTL(A,30); 
  155.   C = SHS_ROTL(D,5)+SHS_F1(E,A,B)+C+ctx->W[ 2]+0x5a827999L; E=SHS_ROTL(E,30); 
  156.   B = SHS_ROTL(C,5)+SHS_F1(D,E,A)+B+ctx->W[ 3]+0x5a827999L; D=SHS_ROTL(D,30); 
  157.   A = SHS_ROTL(B,5)+SHS_F1(C,D,E)+A+ctx->W[ 4]+0x5a827999L; C=SHS_ROTL(C,30); 
  158.   E = SHS_ROTL(A,5)+SHS_F1(B,C,D)+E+ctx->W[ 5]+0x5a827999L; B=SHS_ROTL(B,30); 
  159.   D = SHS_ROTL(E,5)+SHS_F1(A,B,C)+D+ctx->W[ 6]+0x5a827999L; A=SHS_ROTL(A,30); 
  160.   C = SHS_ROTL(D,5)+SHS_F1(E,A,B)+C+ctx->W[ 7]+0x5a827999L; E=SHS_ROTL(E,30); 
  161.   B = SHS_ROTL(C,5)+SHS_F1(D,E,A)+B+ctx->W[ 8]+0x5a827999L; D=SHS_ROTL(D,30); 
  162.   A = SHS_ROTL(B,5)+SHS_F1(C,D,E)+A+ctx->W[ 9]+0x5a827999L; C=SHS_ROTL(C,30); 
  163.   E = SHS_ROTL(A,5)+SHS_F1(B,C,D)+E+ctx->W[10]+0x5a827999L; B=SHS_ROTL(B,30); 
  164.   D = SHS_ROTL(E,5)+SHS_F1(A,B,C)+D+ctx->W[11]+0x5a827999L; A=SHS_ROTL(A,30); 
  165.   C = SHS_ROTL(D,5)+SHS_F1(E,A,B)+C+ctx->W[12]+0x5a827999L; E=SHS_ROTL(E,30); 
  166.   B = SHS_ROTL(C,5)+SHS_F1(D,E,A)+B+ctx->W[13]+0x5a827999L; D=SHS_ROTL(D,30); 
  167.   A = SHS_ROTL(B,5)+SHS_F1(C,D,E)+A+ctx->W[14]+0x5a827999L; C=SHS_ROTL(C,30); 
  168.   E = SHS_ROTL(A,5)+SHS_F1(B,C,D)+E+ctx->W[15]+0x5a827999L; B=SHS_ROTL(B,30); 
  169.   D = SHS_ROTL(E,5)+SHS_F1(A,B,C)+D+ctx->W[16]+0x5a827999L; A=SHS_ROTL(A,30); 
  170.   C = SHS_ROTL(D,5)+SHS_F1(E,A,B)+C+ctx->W[17]+0x5a827999L; E=SHS_ROTL(E,30); 
  171.   B = SHS_ROTL(C,5)+SHS_F1(D,E,A)+B+ctx->W[18]+0x5a827999L; D=SHS_ROTL(D,30); 
  172.   A = SHS_ROTL(B,5)+SHS_F1(C,D,E)+A+ctx->W[19]+0x5a827999L; C=SHS_ROTL(C,30); 
  173.  
  174.   E = SHS_ROTL(A,5)+SHS_F2(B,C,D)+E+ctx->W[20]+0x6ed9eba1L; B=SHS_ROTL(B,30); 
  175.   D = SHS_ROTL(E,5)+SHS_F2(A,B,C)+D+ctx->W[21]+0x6ed9eba1L; A=SHS_ROTL(A,30); 
  176.   C = SHS_ROTL(D,5)+SHS_F2(E,A,B)+C+ctx->W[22]+0x6ed9eba1L; E=SHS_ROTL(E,30); 
  177.   B = SHS_ROTL(C,5)+SHS_F2(D,E,A)+B+ctx->W[23]+0x6ed9eba1L; D=SHS_ROTL(D,30); 
  178.   A = SHS_ROTL(B,5)+SHS_F2(C,D,E)+A+ctx->W[24]+0x6ed9eba1L; C=SHS_ROTL(C,30); 
  179.   E = SHS_ROTL(A,5)+SHS_F2(B,C,D)+E+ctx->W[25]+0x6ed9eba1L; B=SHS_ROTL(B,30); 
  180.   D = SHS_ROTL(E,5)+SHS_F2(A,B,C)+D+ctx->W[26]+0x6ed9eba1L; A=SHS_ROTL(A,30); 
  181.   C = SHS_ROTL(D,5)+SHS_F2(E,A,B)+C+ctx->W[27]+0x6ed9eba1L; E=SHS_ROTL(E,30); 
  182.   B = SHS_ROTL(C,5)+SHS_F2(D,E,A)+B+ctx->W[28]+0x6ed9eba1L; D=SHS_ROTL(D,30); 
  183.   A = SHS_ROTL(B,5)+SHS_F2(C,D,E)+A+ctx->W[29]+0x6ed9eba1L; C=SHS_ROTL(C,30); 
  184.   E = SHS_ROTL(A,5)+SHS_F2(B,C,D)+E+ctx->W[30]+0x6ed9eba1L; B=SHS_ROTL(B,30); 
  185.   D = SHS_ROTL(E,5)+SHS_F2(A,B,C)+D+ctx->W[31]+0x6ed9eba1L; A=SHS_ROTL(A,30); 
  186.   C = SHS_ROTL(D,5)+SHS_F2(E,A,B)+C+ctx->W[32]+0x6ed9eba1L; E=SHS_ROTL(E,30); 
  187.   B = SHS_ROTL(C,5)+SHS_F2(D,E,A)+B+ctx->W[33]+0x6ed9eba1L; D=SHS_ROTL(D,30); 
  188.   A = SHS_ROTL(B,5)+SHS_F2(C,D,E)+A+ctx->W[34]+0x6ed9eba1L; C=SHS_ROTL(C,30); 
  189.   E = SHS_ROTL(A,5)+SHS_F2(B,C,D)+E+ctx->W[35]+0x6ed9eba1L; B=SHS_ROTL(B,30); 
  190.   D = SHS_ROTL(E,5)+SHS_F2(A,B,C)+D+ctx->W[36]+0x6ed9eba1L; A=SHS_ROTL(A,30); 
  191.   C = SHS_ROTL(D,5)+SHS_F2(E,A,B)+C+ctx->W[37]+0x6ed9eba1L; E=SHS_ROTL(E,30); 
  192.   B = SHS_ROTL(C,5)+SHS_F2(D,E,A)+B+ctx->W[38]+0x6ed9eba1L; D=SHS_ROTL(D,30); 
  193.   A = SHS_ROTL(B,5)+SHS_F2(C,D,E)+A+ctx->W[39]+0x6ed9eba1L; C=SHS_ROTL(C,30); 
  194.  
  195.   E = SHS_ROTL(A,5)+SHS_F3(B,C,D)+E+ctx->W[40]+0x8f1bbcdcL; B=SHS_ROTL(B,30); 
  196.   D = SHS_ROTL(E,5)+SHS_F3(A,B,C)+D+ctx->W[41]+0x8f1bbcdcL; A=SHS_ROTL(A,30); 
  197.   C = SHS_ROTL(D,5)+SHS_F3(E,A,B)+C+ctx->W[42]+0x8f1bbcdcL; E=SHS_ROTL(E,30); 
  198.   B = SHS_ROTL(C,5)+SHS_F3(D,E,A)+B+ctx->W[43]+0x8f1bbcdcL; D=SHS_ROTL(D,30); 
  199.   A = SHS_ROTL(B,5)+SHS_F3(C,D,E)+A+ctx->W[44]+0x8f1bbcdcL; C=SHS_ROTL(C,30); 
  200.   E = SHS_ROTL(A,5)+SHS_F3(B,C,D)+E+ctx->W[45]+0x8f1bbcdcL; B=SHS_ROTL(B,30); 
  201.   D = SHS_ROTL(E,5)+SHS_F3(A,B,C)+D+ctx->W[46]+0x8f1bbcdcL; A=SHS_ROTL(A,30); 
  202.   C = SHS_ROTL(D,5)+SHS_F3(E,A,B)+C+ctx->W[47]+0x8f1bbcdcL; E=SHS_ROTL(E,30); 
  203.   B = SHS_ROTL(C,5)+SHS_F3(D,E,A)+B+ctx->W[48]+0x8f1bbcdcL; D=SHS_ROTL(D,30); 
  204.   A = SHS_ROTL(B,5)+SHS_F3(C,D,E)+A+ctx->W[49]+0x8f1bbcdcL; C=SHS_ROTL(C,30); 
  205.   E = SHS_ROTL(A,5)+SHS_F3(B,C,D)+E+ctx->W[50]+0x8f1bbcdcL; B=SHS_ROTL(B,30); 
  206.   D = SHS_ROTL(E,5)+SHS_F3(A,B,C)+D+ctx->W[51]+0x8f1bbcdcL; A=SHS_ROTL(A,30); 
  207.   C = SHS_ROTL(D,5)+SHS_F3(E,A,B)+C+ctx->W[52]+0x8f1bbcdcL; E=SHS_ROTL(E,30); 
  208.   B = SHS_ROTL(C,5)+SHS_F3(D,E,A)+B+ctx->W[53]+0x8f1bbcdcL; D=SHS_ROTL(D,30); 
  209.   A = SHS_ROTL(B,5)+SHS_F3(C,D,E)+A+ctx->W[54]+0x8f1bbcdcL; C=SHS_ROTL(C,30); 
  210.   E = SHS_ROTL(A,5)+SHS_F3(B,C,D)+E+ctx->W[55]+0x8f1bbcdcL; B=SHS_ROTL(B,30); 
  211.   D = SHS_ROTL(E,5)+SHS_F3(A,B,C)+D+ctx->W[56]+0x8f1bbcdcL; A=SHS_ROTL(A,30); 
  212.   C = SHS_ROTL(D,5)+SHS_F3(E,A,B)+C+ctx->W[57]+0x8f1bbcdcL; E=SHS_ROTL(E,30); 
  213.   B = SHS_ROTL(C,5)+SHS_F3(D,E,A)+B+ctx->W[58]+0x8f1bbcdcL; D=SHS_ROTL(D,30); 
  214.   A = SHS_ROTL(B,5)+SHS_F3(C,D,E)+A+ctx->W[59]+0x8f1bbcdcL; C=SHS_ROTL(C,30); 
  215.  
  216.   E = SHS_ROTL(A,5)+SHS_F4(B,C,D)+E+ctx->W[60]+0xca62c1d6L; B=SHS_ROTL(B,30); 
  217.   D = SHS_ROTL(E,5)+SHS_F4(A,B,C)+D+ctx->W[61]+0xca62c1d6L; A=SHS_ROTL(A,30); 
  218.   C = SHS_ROTL(D,5)+SHS_F4(E,A,B)+C+ctx->W[62]+0xca62c1d6L; E=SHS_ROTL(E,30); 
  219.   B = SHS_ROTL(C,5)+SHS_F4(D,E,A)+B+ctx->W[63]+0xca62c1d6L; D=SHS_ROTL(D,30); 
  220.   A = SHS_ROTL(B,5)+SHS_F4(C,D,E)+A+ctx->W[64]+0xca62c1d6L; C=SHS_ROTL(C,30); 
  221.   E = SHS_ROTL(A,5)+SHS_F4(B,C,D)+E+ctx->W[65]+0xca62c1d6L; B=SHS_ROTL(B,30); 
  222.   D = SHS_ROTL(E,5)+SHS_F4(A,B,C)+D+ctx->W[66]+0xca62c1d6L; A=SHS_ROTL(A,30); 
  223.   C = SHS_ROTL(D,5)+SHS_F4(E,A,B)+C+ctx->W[67]+0xca62c1d6L; E=SHS_ROTL(E,30); 
  224.   B = SHS_ROTL(C,5)+SHS_F4(D,E,A)+B+ctx->W[68]+0xca62c1d6L; D=SHS_ROTL(D,30); 
  225.   A = SHS_ROTL(B,5)+SHS_F4(C,D,E)+A+ctx->W[69]+0xca62c1d6L; C=SHS_ROTL(C,30); 
  226.   E = SHS_ROTL(A,5)+SHS_F4(B,C,D)+E+ctx->W[70]+0xca62c1d6L; B=SHS_ROTL(B,30); 
  227.   D = SHS_ROTL(E,5)+SHS_F4(A,B,C)+D+ctx->W[71]+0xca62c1d6L; A=SHS_ROTL(A,30); 
  228.   C = SHS_ROTL(D,5)+SHS_F4(E,A,B)+C+ctx->W[72]+0xca62c1d6L; E=SHS_ROTL(E,30); 
  229.   B = SHS_ROTL(C,5)+SHS_F4(D,E,A)+B+ctx->W[73]+0xca62c1d6L; D=SHS_ROTL(D,30); 
  230.   A = SHS_ROTL(B,5)+SHS_F4(C,D,E)+A+ctx->W[74]+0xca62c1d6L; C=SHS_ROTL(C,30); 
  231.   E = SHS_ROTL(A,5)+SHS_F4(B,C,D)+E+ctx->W[75]+0xca62c1d6L; B=SHS_ROTL(B,30); 
  232.   D = SHS_ROTL(E,5)+SHS_F4(A,B,C)+D+ctx->W[76]+0xca62c1d6L; A=SHS_ROTL(A,30); 
  233.   C = SHS_ROTL(D,5)+SHS_F4(E,A,B)+C+ctx->W[77]+0xca62c1d6L; E=SHS_ROTL(E,30); 
  234.   B = SHS_ROTL(C,5)+SHS_F4(D,E,A)+B+ctx->W[78]+0xca62c1d6L; D=SHS_ROTL(D,30); 
  235.   A = SHS_ROTL(B,5)+SHS_F4(C,D,E)+A+ctx->W[79]+0xca62c1d6L; C=SHS_ROTL(C,30); 
  236.  
  237.   ctx->H[0] += A;
  238.   ctx->H[1] += B;
  239.   ctx->H[2] += C;
  240.   ctx->H[3] += D;
  241.   ctx->H[4] += E;
  242. }
  243.  
  244.